package com.ruicar.afs.cloud.image.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.rules.RuleHelper;
import com.ruicar.afs.cloud.common.rules.constants.RuleRunEnum;
import com.ruicar.afs.cloud.common.rules.dto.RuleResult;
import com.ruicar.afs.cloud.common.rules.dto.RuleRunResult;
import com.ruicar.afs.cloud.components.datadicsync.DicHelper;
import com.ruicar.afs.cloud.components.datadicsync.dto.DicDataDto;
import com.ruicar.afs.cloud.image.condition.AuditCondition;
import com.ruicar.afs.cloud.image.config.FileProperties;
import com.ruicar.afs.cloud.image.entity.ComAttachmentFile;
import com.ruicar.afs.cloud.image.entity.ComAttachmentManagement;
import com.ruicar.afs.cloud.image.entity.ComAttachmentRule;
import com.ruicar.afs.cloud.image.enums.*;
import com.ruicar.afs.cloud.image.mapper.ComAttachmentManagementMapper;
import com.ruicar.afs.cloud.image.service.ComAttaManageService;
import com.ruicar.afs.cloud.image.service.ComAttachmentFileService;
import com.ruicar.afs.cloud.image.service.ComAttachmentRuleService;
import com.ruicar.afs.cloud.image.util.DrawImg;
import com.ruicar.afs.cloud.image.vo.AuditFileVo;
import com.ruicar.afs.cloud.image.vo.UploadInputVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description:
 * @Author: fangchenliang
 * @Date: 2020/5/15 21:05
 */
@Service
@Slf4j
public class ComAttaManageServiceImpl extends ServiceImpl<ComAttachmentManagementMapper, ComAttachmentManagement> implements ComAttaManageService {
    @Autowired
    private ComAttachmentFileService comAttachmentFileService;
    @Autowired
    private ComAttachmentRuleService comAttachmentRuleService;
    @Autowired
    private FileProperties fileProperties;
    @Autowired
    private DrawImg drawImg;

    public List<ComAttachmentManagement> getUploadList(JSONObject runParams, List<ComAttachmentManagement> AllComAttachmentManagementList) {
        List<ComAttachmentManagement> uploadList = new ArrayList<>();
        AllComAttachmentManagementList.forEach(comAttachmentManagement -> {
            if (comAttachmentManagement.getAttachmentClass() == (AttachmentClassEnum.CATEGORY.getCode())) {
                List<ComAttachmentManagement> childList = comAttachmentManagement.getChildren();
                childList.forEach(childAttachmentManagement -> {
                    boolean skipGroupRule = childAttachmentManagement.getAttachmentClass() == (AttachmentClassEnum.GROUP.getCode())
                            && StringUtils.isEmpty(childAttachmentManagement.getRuleId())
                            && childAttachmentManagement.getChildren().size() > 0;
                    if (skipGroupRule) {
                        List<ComAttachmentManagement> childrens = childAttachmentManagement.getChildren();
                        childrens.forEach(child -> {
                            child = comAttachmentManagementHitRule(runParams, child);
                            if (!child.isHit()) {
                                childrens.remove(child);
                            }
                        });
                        if (childrens == null || childrens.size() == 0) {
                            childList.remove(childAttachmentManagement);
                        }
                    } else {
                        childAttachmentManagement = comAttachmentManagementHitRule(runParams, childAttachmentManagement);
                        if (!childAttachmentManagement.isHit()) {
                            childList.remove(childAttachmentManagement);
                        }
                    }

                });
            }
            uploadList.add(comAttachmentManagement);
        });
        return uploadList;
    }


    public ComAttachmentManagement comAttachmentManagementHitRule(JSONObject runParams, ComAttachmentManagement comAttachmentManagement) {
        Boolean isRule = comAttachmentManagement.getNeedType().equals(NeedTypeEnum.RULE.getCode())
                && comAttachmentManagement.getIsEnableRule().equals(IsEnableRuleEnum.YES.getCode());
        if (isRule) {
            RuleRunResult ruleRunResult = resolveRule(runParams, comAttachmentManagement);
            boolean isHit = ruleRunResult.getHit() || ruleRunResult.getResults().size() > 0;
            if (isHit) {
                List<RuleResult> ruleResults = ruleRunResult.getResults();
                if (ruleResults.size() == 1) {
                    /**影像件配置规则满足条件的情况下只能匹配出一条规则*/
                    RuleResult ruleResult = ruleResults.get(0);
                    ComAttachmentRule comAttachmentRule = comAttachmentRuleService.getById(ruleResult.getRuleNo());
                    comAttachmentManagement.setNeedNums(Integer.valueOf(comAttachmentRule.getRuleValue()));
                    comAttachmentManagement.setHit(true);
                } else {
                    /**命中规则但没有返回值或者参数匹配出所有规则（属于错误规则），只显示即可(NeedNums=0)*/
                    comAttachmentManagement.setNeedNums(0);
                    comAttachmentManagement.setHit(true);
                }
            } else {
                comAttachmentManagement.setHit(false);
            }
        } else {
            if (comAttachmentManagement.getNeedType().equals(NeedTypeEnum.MUST)) {
                comAttachmentManagement.setNeedNums(comAttachmentManagement.getItemNum());
            }
            if (comAttachmentManagement.getNeedType().equals(NeedTypeEnum.ONLYSHOW)) {
                comAttachmentManagement.setNeedNums(0);
            }
            comAttachmentManagement.setHit(true);
        }
        return comAttachmentManagement;
    }

    public RuleRunResult resolveRule(JSONObject runParams, ComAttachmentManagement comAttachmentManagement) {
        List<ComAttachmentRule> rules = comAttachmentRuleService.list(Wrappers.<ComAttachmentRule>query().lambda()
                .eq(ComAttachmentRule::getAttachmentId, comAttachmentManagement.getId()));
        List<String> ruleNoList = rules.stream().map(s -> String.valueOf(s.getId())).collect(Collectors.toList());
        RuleRunResult ruleRunResult = RuleHelper.runRule(runParams, ruleNoList, false, RuleRunEnum.PARALLEL);
        return ruleRunResult;
    }

    public ComAttachmentManagement CollectFileInfo(ComAttachmentManagement comAttachmentManagement, String busiNo) {
        List<ComAttachmentFile> fileList = comAttachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                .eq(ComAttachmentFile::getAttachmentCode, comAttachmentManagement.getId())
                .eq(ComAttachmentFile::getBusiNo, busiNo));
        return comAttachmentManagement;
    }

    public List<ComAttachmentManagement> getAttaListByRule(JSONObject runParams, String busiType) {
        String[] strs = busiType.split(",");
        List busiNodes = Arrays.asList(strs);
        List<ComAttachmentManagement> attaList = this.list(Wrappers.<ComAttachmentManagement>query().lambda()
                .in(StringUtils.isNotEmpty(busiType), ComAttachmentManagement::getBusiNode, busiNodes)
        );
        attaList.forEach(comAttachmentManagement -> {
            if (comAttachmentManagement.getAttachmentClass() == AttachmentClassEnum.GROUP.getCode()) {
                comAttachmentManagement = comAttachmentManagementHitRule(runParams, comAttachmentManagement);
                /**不存在组和它的子小类同时都命中规则的情况，如果组生效了规则，那么它的子小类规则必定是失效状态*/
                if (!comAttachmentManagement.isHit()) {
                    ComAttachmentManagement finalComAttachmentManagement = comAttachmentManagement;
                    attaList.stream().filter(manage ->
                            !finalComAttachmentManagement.getId().equals(manage.getParentId())
                                    && !finalComAttachmentManagement.getId().equals(manage.getId()))
                            .collect(Collectors.toList());
                }
            }
            if (comAttachmentManagement.getAttachmentClass() == AttachmentClassEnum.SUBCLASS.getCode()) {
                comAttachmentManagement = comAttachmentManagementHitRule(runParams, comAttachmentManagement);
                if (!comAttachmentManagement.isHit()) {
                    ComAttachmentManagement finalComAttachmentManagement = comAttachmentManagement;
                    attaList.stream().filter(manage -> !finalComAttachmentManagement.getId().equals(manage.getId()))
                            .collect(Collectors.toList());
                }
            }
        });
        return attaList;
    }

    public List<ComAttachmentManagement> getAllFileList(String busiNo, String busiType) {
        List<ComAttachmentManagement> uploadFileList = new ArrayList<>();
        Map map = new HashMap();
        map.put("busiNode", busiType.split(","));
        String[] str = busiType.split(",");
        List<String> list = Arrays.asList(str);
        List<ComAttachmentFile> fileList = comAttachmentFileService.findUploadFileByBusiNo(busiNo, list);
        Map<String, List<ComAttachmentFile>> filesMap = fileList.stream().collect(Collectors.groupingBy(ComAttachmentFile::getAttachmentCode));
        Iterator it = filesMap.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next().toString();
            List<ComAttachmentManagement> attaList = this.list(
                    Wrappers.<ComAttachmentManagement>query().lambda()
                            .eq(ComAttachmentManagement::getId, Long.valueOf(key)));
            attaList.get(0).setFileList(filesMap.get(key));
            uploadFileList = Stream.of(uploadFileList, attaList)
                    .flatMap(Collection::stream)
                    .distinct()
                    .collect(Collectors.toList());
        }
        return uploadFileList;
    }

    public List<ComAttachmentManagement> invokeParent(List<ComAttachmentManagement> comAttachmentManagementList) {
        List<ComAttachmentManagement> resultList = new ArrayList<>();
        if (comAttachmentManagementList.size() > 0) {
            Map<Integer, List<ComAttachmentManagement>> comAttaMap = comAttachmentManagementList.stream()
                    .collect(Collectors.groupingBy(ComAttachmentManagement::getAttachmentClass));
            List<ComAttachmentManagement> categoryAttachmentManagementList = comAttaMap.get(AttachmentClassEnum.CATEGORY.getCode()) == null ? new ArrayList<>() : comAttaMap.get(AttachmentClassEnum.CATEGORY.getCode());
            List<ComAttachmentManagement> groupAttachmentManagementList = comAttaMap.get(AttachmentClassEnum.GROUP.getCode()) == null ? new ArrayList<>() : comAttaMap.get(AttachmentClassEnum.GROUP.getCode());
            List<ComAttachmentManagement> subclassAttachmentManagementList = comAttaMap.get(AttachmentClassEnum.SUBCLASS.getCode()) == null ? new ArrayList<>() : comAttaMap.get(AttachmentClassEnum.SUBCLASS.getCode());
            Map<Long, List<ComAttachmentManagement>> subclassAttachmentManagementMaps = subclassAttachmentManagementList.stream()
                    .collect(Collectors.groupingBy(ComAttachmentManagement::getParentId));
            groupAttachmentManagementList.forEach(group -> {
                List<ComAttachmentManagement> groupAttachmentlist = subclassAttachmentManagementMaps.get(group.getId());
                if (!CollectionUtils.isEmpty(groupAttachmentlist)) {
                    boolean isRuleOut = group.getNeedType().equals(NeedTypeEnum.RULE.getCode())
                            && StringUtils.isNotEmpty(group.getRuleId())
                            && group.getIsEnableRule() == IsEnableRuleEnum.YES.getCode();
                    if (isRuleOut) {
                        groupAttachmentlist.forEach(out -> {
                            out.setNeedNums(0);//设置必传数为0，前端显示不必传
                        });
                    }
                    group.setChildren((List<ComAttachmentManagement>) groupAttachmentlist
                            .stream()
                            .sorted(Comparator.comparing(ComAttachmentManagement::getSortOrder)).collect(Collectors.toList()));
                }
            });
            Map<Long, List<ComAttachmentManagement>> groupAttachmentManagementMaps = groupAttachmentManagementList.stream()
                    .collect(Collectors.groupingBy(ComAttachmentManagement::getParentId));
            categoryAttachmentManagementList.forEach(categoryAttachmentManagement -> {
                List<ComAttachmentManagement> subClassAttachmentlist = subclassAttachmentManagementMaps.get(categoryAttachmentManagement.getId());
                List<ComAttachmentManagement> groupClassAttachmentlist = groupAttachmentManagementMaps.get(categoryAttachmentManagement.getId());
                List<ComAttachmentManagement> categoryChilrenList = new ArrayList<>();
                if (subClassAttachmentlist != null) {
                    categoryChilrenList.addAll(subClassAttachmentlist);
                }
                if (groupClassAttachmentlist != null) {
                    categoryChilrenList.addAll(groupClassAttachmentlist);
                }
                categoryChilrenList = categoryChilrenList.stream().sorted(Comparator.comparing(ComAttachmentManagement::getSortOrder)).collect(Collectors.toList());
                categoryAttachmentManagement.setChildren(categoryChilrenList);
                resultList.add(categoryAttachmentManagement);
            });
        }
        return resultList;
    }

    /**
     * @param title
     * @return list
     * @Description: 模糊搜索
     * @Author: tianaki
     */
    @Override
    public List<ComAttachmentManagement> findByAttachmentName(String title) {
        return this.list(Wrappers
                .<ComAttachmentManagement>query().lambda()
                .like(ComAttachmentManagement::getAttachmentName, title).orderByAsc(ComAttachmentManagement::getAttachmentClass));
    }

    public List<ComAttachmentManagement> getManagementByRuleGroup(JSONObject runParams, String groupId) {
        String[] str = groupId.split(",");
        List<ComAttachmentManagement> allManagementList = this.list(Wrappers.<ComAttachmentManagement>query().lambda()
                .in(ComAttachmentManagement::getBusiNode, str).eq(ComAttachmentManagement::getIsEnableRule,IsEnableRuleEnum.YES.getCode()));
        List<ComAttachmentManagement> outList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(allManagementList)) {
            Map<Long, String> ruleValueMap = new HashMap<>();
            log.info("规则组：{}=>开始执行规则", groupId);
            for (int i = 0; i < str.length; i++) {
                try {
                    RuleRunResult ruleRunResult = RuleHelper.runByGroup(runParams, str[i], false, RuleRunEnum.PARALLEL, false);
                    boolean isHit = ruleRunResult.getHit();
                    log.info("规则组：{}=>执行结束，结果：{}", str[i], isHit);
                    if (isHit) {
                        List<RuleResult> ruleResults = ruleRunResult.getResults();
                        ruleResults.forEach(ruleResult -> {
                            String ruleNo = ruleResult.getRuleNo();
                            ComAttachmentRule comAttachmentRule = comAttachmentRuleService.getById(Long.valueOf(ruleNo));
                            String ruleValue = comAttachmentRule.getRuleValue();
                            ComAttachmentManagement comAttachmentManagement = this.getById(comAttachmentRule.getAttachmentId());
                            ruleValueMap.put(comAttachmentManagement.getId(), ruleValue);
                        });
                    }
                } catch (Exception e) {
                    log.info("规则组{}:执行失败", str[i],e);
                }
            }
            Map<Long, List<ComAttachmentManagement>> groupMap = allManagementList.stream().collect(Collectors.groupingBy(ComAttachmentManagement::getParentId));
            Map<Long, ComAttachmentManagement> parentAttachmentMap = allManagementList.stream().collect(Collectors.toMap(ComAttachmentManagement::getId, m -> m));
            allManagementList.forEach(management -> {
                if (management.getNeedType().equals(NeedTypeEnum.MUST.getCode())) {
                    management.setNeedNums(management.getItemNum());
                    management.setHit(true);
                    if (management.getAttachmentClass() == AttachmentClassEnum.SUBCLASS.getCode()) {
                        ComAttachmentManagement parentAttachment = parentAttachmentMap.get(management.getParentId());
                        parentAttachment.setHit(true);
                    }
                }
                if (management.getNeedType().equals(NeedTypeEnum.ONLYSHOW.getCode())) {
                    management.setNeedNums(0);
                    management.setHit(true);
                    if (management.getAttachmentClass() == AttachmentClassEnum.SUBCLASS.getCode()) {
                        ComAttachmentManagement parentAttachment = parentAttachmentMap.get(management.getParentId());
                        parentAttachment.setHit(true);
                    }
                }
                if (management.getNeedType().equals(NeedTypeEnum.RULE.getCode())) {
                    if (ruleValueMap.size() > 0 && ruleValueMap.containsKey(management.getId())) {
                        management.setNeedNums(Integer.valueOf(ruleValueMap.get(management.getId())));
                        management.setHit(true);
                        if (management.getAttachmentClass() == AttachmentClassEnum.GROUP.getCode()) {
                            List<ComAttachmentManagement> list = groupMap.get(management.getId());
                            list.forEach(comAttachmentManagement -> {
                                comAttachmentManagement.setHit(true);
                            });
                        }
                    }
                }
                outList.add(management);
            });

            /**删除没有命中*/
            outList.removeIf(management -> (!management.isHit())
                    && (management.getAttachmentClass() == AttachmentClassEnum.SUBCLASS.getCode() || management.getAttachmentClass() == AttachmentClassEnum.GROUP.getCode()));
        } else {
            log.error("未找到业务节点：{}", groupId);
            return new ArrayList<>();
        }
        return outList;
    }


    /**获取图片文件*/
    public ComAttachmentFile getFile(String uniqueCode,String busiNo){
        ComAttachmentManagement comAttachmentManagement=this.getOne(Wrappers.<ComAttachmentManagement>query().lambda()
                .eq(ComAttachmentManagement::getUniqueCode,uniqueCode),false);
        if(!ObjectUtils.isEmpty(comAttachmentManagement)) {
            List<ComAttachmentFile> comAttachmentFiles = comAttachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                    .eq(ComAttachmentFile::getAttachmentCode, String.valueOf(comAttachmentManagement.getId()))
                    .eq(ComAttachmentFile::getBusiNo,busiNo)
                    .orderByDesc(ComAttachmentFile::getUploadTime));
            if(!CollectionUtils.isEmpty(comAttachmentFiles)){
                return comAttachmentFiles.get(0);
            }else{
                log.error("{}：{}未找到相应图片数据！",busiNo,uniqueCode);
                return new ComAttachmentFile() ;
            }
        }else {
            log.error("{}未找到相应影像件类型！",uniqueCode);
            return new ComAttachmentFile();
        }
    }
    public List<ComAttachmentFile> getFileList(List<ComAttachmentFile> fileList,String busiNo,String belongNo,ComAttachmentManagement comAttachmentManagement,String version){
        List<ComAttachmentManagement> childManagements=comAttachmentManagement.getChildren();
        List<ComAttachmentFile> comAttachmentFiles=comAttachmentFileService.list(Wrappers.<ComAttachmentFile>lambdaQuery()
                .eq(ComAttachmentFile::getAttachmentCode,String.valueOf(comAttachmentManagement.getId()))
                .eq(ComAttachmentFile::getBusiNo,busiNo)
                .eq(ComAttachmentFile::getBelongNo,belongNo)
                .eq(StringUtils.isNotBlank(version),ComAttachmentFile::getHistoryVersion, version));
        if(!CollectionUtils.isEmpty(childManagements)){
            childManagements.forEach(child->{
                getFileList(fileList,busiNo,belongNo,child,version);
            });
        }
        fileList.addAll(comAttachmentFiles);
        return fileList;
    }
    @Override
    public List<AuditFileVo> getLoanAllFileList(AuditCondition auditCondition) {
        List list = Arrays.asList(auditCondition.getBusiNodes().split(","));
        auditCondition.setList(list);
        //查询附件信息
        List<String> version=new ArrayList<>();
        if(com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotEmpty(auditCondition.getHistoryVersion())){
            if(!auditCondition.getHistoryVersion().equals("all")){
                version.add("0");
                version.add(auditCondition.getHistoryVersion()) ;
            }
        }
        List<String> attachmentIds=this.list(Wrappers.<ComAttachmentManagement>lambdaQuery()
                .in(ComAttachmentManagement::getBusiNode,list))
                .stream()
                .map(m -> String.valueOf(m.getId())).collect(Collectors.toList());
        List<ComAttachmentFile> fileList = comAttachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                .in(ComAttachmentFile::getAttachmentCode,attachmentIds)
                .eq(ComAttachmentFile::getBusiNo, auditCondition.getBusiNo())
                .eq(ComAttachmentFile::getBelongNo, auditCondition.getBelongNo())
                .in(!CollectionUtils.isEmpty(version),ComAttachmentFile::getHistoryVersion, version));
        Map<String, List<DicDataDto>> groupDicMap=DicHelper.getDicMaps("imageGroupUnicode");
        List<String> dicValues=new ArrayList<>();
        if(!CollectionUtils.isEmpty(groupDicMap)){
            dicValues=groupDicMap.get("imageGroupUnicode").stream().map(dicDataDto ->dicDataDto.getValue()).collect(Collectors.toList());
        }
        if(!CollectionUtils.isEmpty(fileList)){
            Map<String,List<ComAttachmentFile>> fileMap=fileList.stream().collect(Collectors.groupingBy(ComAttachmentFile::getAttachmentCode));
            List<String> finalDicValues = dicValues;
            List<ComAttachmentManagement> spList=new ArrayList<>();
            Iterator<Map.Entry<String, List<ComAttachmentFile>>> it= fileMap.entrySet().iterator();
            while (it.hasNext()){
                Map.Entry<String, List<ComAttachmentFile>> entry = it.next();
                ComAttachmentManagement management = this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery().eq(ComAttachmentManagement::getId, Long.valueOf(entry.getKey())));
                ComAttachmentManagement parent = this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery().eq(ComAttachmentManagement::getId, Long.valueOf(management.getParentId())));
                if (finalDicValues.contains(parent.getUniqueCode())) {
                    management.setFileList(entry.getValue().stream().sorted(Comparator.comparing(ComAttachmentFile::getUploadTime)).collect(Collectors.toList()));
                    spList.add(management);
                    it.remove();
                }
            }
            List<AuditFileVo> auditFileVos=new ArrayList<>();
            List<ComAttachmentManagement> orderList=spList.stream().sorted(Comparator.comparing(ComAttachmentManagement::getSortOrder)).collect(Collectors.toList());
            Map<Long,List<ComAttachmentManagement>> spFileMap=orderList.stream().collect(Collectors.groupingBy(ComAttachmentManagement::getParentId));
            Iterator<Map.Entry<Long, List<ComAttachmentManagement>>> iterator = spFileMap.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<Long, List<ComAttachmentManagement>> entry = iterator.next();
                ComAttachmentManagement comAttachmentManagement=this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery().eq(ComAttachmentManagement::getId, entry.getKey()));
                AuditFileVo vo=new AuditFileVo();
                boolean attachmentStatus=true;
                BeanUtil.copyProperties(comAttachmentManagement,vo);
                List<ComAttachmentFile> childFileList= new ArrayList<>();
                for (ComAttachmentManagement management:entry.getValue()){
                    childFileList.addAll(management.getFileList());
                }
                for(ComAttachmentFile file:childFileList){
                    if(file.getFileStatus().equals(FileStatusEnum.NOTSTANDARD.getCode())||file.getFileStatus().equals(FileStatusEnum.WAITAPPROVE.getCode())){
                        attachmentStatus=false;
                    }
                }
                vo.setAttachmentStatus(attachmentStatus);
                vo.setUserId(SecurityUtils.getUsername());
                vo.setFileList(childFileList);
                vo.setAttachmentCode(entry.getKey().toString());
                auditFileVos.add(vo);
            }
            fileMap.forEach((key, value)->{
                boolean attachmentStatus=true;
                AuditFileVo auditFileVo=new AuditFileVo();
                auditFileVo.setUserId(SecurityUtils.getUsername());
                auditFileVo.setViewTime(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                ComAttachmentManagement management=this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery().eq(ComAttachmentManagement::getId,Long.valueOf(key)));
                BeanUtil.copyProperties(management,auditFileVo);
                auditFileVo.setFileList(value);
                for(ComAttachmentFile file:value){
                    if(file.getFileStatus().equals(FileStatusEnum.NOTSTANDARD.getCode())||file.getFileStatus().equals(FileStatusEnum.WAITAPPROVE.getCode())){
                        attachmentStatus=false;
                    }
                }
                auditFileVo.setAttachmentCode(key);
                auditFileVo.setAttachmentStatus(attachmentStatus);
                auditFileVos.add(auditFileVo);
            });
            ComAttachmentManagement otherManagement=this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery().eq(ComAttachmentManagement::getUniqueCode, AttachmentUniqueCodeEnum.LOAN_OTHER.getCode()),false);
            /**添加其他类型*/
            if(com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotEmpty(otherManagement)){
                List<AuditFileVo> otherVos=auditFileVos.stream().filter(m->m.getAttachmentCode().equals(otherManagement.getId().toString())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(otherVos)){
                    AuditFileVo auditFileVo=new AuditFileVo();
                    BeanUtil.copyProperties(otherManagement,auditFileVo);
                    auditFileVo.setUserId(SecurityUtils.getUsername());
                    auditFileVo.setViewTime(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                    auditFileVo.setAttachmentCode(otherManagement.getId().toString());
                    auditFileVo.setAttachmentStatus(true);
                    auditFileVos.add(auditFileVo);
                }
            }
            return auditFileVos.stream().sorted(Comparator.comparing(AuditFileVo::getSortOrder)).collect(Collectors.toList());
        }else {
            return new ArrayList<>();
        }
    }

    public List<AuditFileVo> getFileByUniqueCode(String uniqueCodes,String busiNo,String belongNo){
        String[] uniqueCode= uniqueCodes.split(",");
        List<ComAttachmentManagement> managements=this.list(Wrappers.<ComAttachmentManagement>lambdaQuery()
                .in(ComAttachmentManagement::getUniqueCode,uniqueCode));
        List<AuditFileVo> list= new ArrayList<>();
        managements.forEach(m->{
            AuditFileVo auditFileVo=new AuditFileVo();
            List<ComAttachmentFile> files=comAttachmentFileService.list(Wrappers.<ComAttachmentFile>lambdaQuery()
                    .eq(ComAttachmentFile::getBusiNo,busiNo)
                    .eq(ComAttachmentFile::getBelongNo,belongNo)
                    .in(ComAttachmentFile::getAttachmentCode,m.getId().toString())
                    .eq(ComAttachmentFile::getFileStatus,FileStatusEnum.STANDARD.getCode()));
            auditFileVo.setBusiNode(m.getBusiNode());
            auditFileVo.setAttachmentCode(m.getId().toString());
            auditFileVo.setAttachmentName(m.getAttachmentName());
            auditFileVo.setFileList(files);
            list.add(auditFileVo);
        });
        return list;
    }

    public void changeFileVersion(String contractNo,String attachmentCode){
        /**如果attachmentCode是组，需要找出组下的真实文件类型*/
        ComAttachmentManagement management=this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery().eq(ComAttachmentManagement::getId,Long.valueOf(attachmentCode)));
        if(management.getAttachmentClass()== AttachmentClassEnum.GROUP.getCode()){
            log.info("修改合同号码{}:文件版本开始===",contractNo);
            List<ComAttachmentManagement> list=this.list(Wrappers.<ComAttachmentManagement>lambdaQuery()
                    .eq(ComAttachmentManagement::getParentId,Long.valueOf(attachmentCode)));
            list.forEach(comAttachmentManagement->{
                List<ComAttachmentFile> files=comAttachmentFileService.list(Wrappers.<ComAttachmentFile>lambdaQuery()
                        .eq(ComAttachmentFile::getBelongNo,contractNo)
                        .eq(ComAttachmentFile::getBusiNo,contractNo)
                        .eq(ComAttachmentFile::getFileStatus,FileStatusEnum.NOTSTANDARD.getCode())
                        .in(ComAttachmentFile::getAttachmentCode,comAttachmentManagement.getId().toString()));
                if(files.size()>0){
                    Map<String,List<ComAttachmentFile>> map=files.stream().collect(Collectors.groupingBy(ComAttachmentFile::getHistoryVersion));
                    files.forEach(file->{
                        /**文件上传之后，文件版本默认0为当前版，只有退回时把当前版本更新为历史版本*/
                        if(file.getHistoryVersion().equals("0")){
                            file.setHistoryVersion(String.valueOf(map.size()));
                            log.info("修改合同号码{}:文件{}为版本{}",contractNo,file.getFileName(),file.getHistoryVersion());
                            comAttachmentFileService.updateById(file);
                        }
                    });
                }
            });
        }else{
            log.info("修改合同号码{}:文件版本开始===",contractNo);
            List<ComAttachmentFile> files=comAttachmentFileService.list(Wrappers.<ComAttachmentFile>lambdaQuery()
                    .eq(ComAttachmentFile::getBelongNo,contractNo)
                    .eq(ComAttachmentFile::getBusiNo,contractNo)
                    .eq(ComAttachmentFile::getFileStatus,FileStatusEnum.NOTSTANDARD.getCode())
                    .eq(ComAttachmentFile::getAttachmentCode,attachmentCode));
            if(files.size()>0){
                Map<String,List<ComAttachmentFile>> map=files.stream().collect(Collectors.groupingBy(ComAttachmentFile::getHistoryVersion));
                files.forEach(file->{
                    /**文件上传之后，文件版本默认0为当前版，只有退回时把当前版本更新为历史版本*/
                    if(file.getHistoryVersion().equals("0")){
                        file.setHistoryVersion(String.valueOf(map.size()));
                        log.info("修改合同号码{}:文件{}为版本{}",contractNo,file.getFileName(),file.getHistoryVersion());
                        comAttachmentFileService.updateById(file);
                    }
                });
            }
        }
        log.info("修改合同号码{}:文件版本结束===",contractNo);
    }

    public void updateFileVersionByBusiNoForLoan(String contractNo,List<String> attachmentIdList){
        if(!CollectionUtils.isEmpty(attachmentIdList)) {
            attachmentIdList.forEach(id -> {
                /**修改历史不合格文件版本号*/
                changeFileVersion(contractNo,id);

                /**修改新草稿文件状态为不合格状态*/
                List<ComAttachmentFile> newFileList = comAttachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                        .eq(ComAttachmentFile::getBusiNo, contractNo)
                        .eq(ComAttachmentFile::getBelongNo, contractNo)
                        .eq(ComAttachmentFile::getHistoryVersion, "0")
                        .eq(ComAttachmentFile::getFileStatus, FileStatusEnum.DRAFT.getCode()));
                newFileList.forEach(file->{
                    file.setFileStatus(FileStatusEnum.WAITAPPROVE.getCode());
                    comAttachmentFileService.updateById(file);
                });
            });
        }else{
            log.info("{}合同未找到相应的影像件类型",contractNo);
        }
    }
    public void setFileStandard(String contractNo,String attachmentCode){
        ComAttachmentManagement management=this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery().eq(ComAttachmentManagement::getId,attachmentCode));
        if(management.getAttachmentClass()== AttachmentClassEnum.GROUP.getCode()){
            List<ComAttachmentManagement> list=this.list(Wrappers.<ComAttachmentManagement>lambdaQuery()
                    .eq(ComAttachmentManagement::getParentId,Long.valueOf(attachmentCode)));
            list.forEach(comAttachmentManagement -> {
                List<ComAttachmentFile> notStandardList = comAttachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                        .eq(ComAttachmentFile::getBusiNo, contractNo)
                        .eq(ComAttachmentFile::getBelongNo, contractNo)
                        .eq(ComAttachmentFile::getAttachmentCode,comAttachmentManagement.getId().toString())
                        .eq(ComAttachmentFile::getHistoryVersion, "0")
                        .eq(ComAttachmentFile::getFileStatus, FileStatusEnum.WAITAPPROVE.getCode()));
                notStandardList.forEach(comAttachmentFile -> {
                    comAttachmentFile.setFileStatus(FileStatusEnum.STANDARD.getCode());
                    comAttachmentFileService.updateById(comAttachmentFile);
                });
            });
        }else{
            List<ComAttachmentFile> notStandardList = comAttachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                    .eq(ComAttachmentFile::getBusiNo, contractNo)
                    .eq(ComAttachmentFile::getBelongNo, contractNo)
                    .eq(ComAttachmentFile::getAttachmentCode,attachmentCode)
                    .eq(ComAttachmentFile::getHistoryVersion, "0")
                    .eq(ComAttachmentFile::getFileStatus, FileStatusEnum.WAITAPPROVE.getCode()));
            notStandardList.forEach(comAttachmentFile -> {
                comAttachmentFile.setFileStatus(FileStatusEnum.STANDARD.getCode());
                comAttachmentFileService.updateById(comAttachmentFile);
            });
        }
    }
    public void mergeRepayIdCard(String contractNo,String accountName,String certNo) {
        try {
            ComAttachmentManagement management=this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery()
                    .eq(ComAttachmentManagement::getUniqueCode,AttachmentUniqueCodeEnum.REPAY_IDCARD_MERGE.getCode())
                    .eq(ComAttachmentManagement::getBusiNode,BusiNodeEnum.LOAN_APPLY.getCode()));
            if(!ObjectUtils.isEmpty(management)){
                ComAttachmentFile repayIdCardFront = this.getFile(AttachmentUniqueCodeEnum.REPAY_IDCARD_FRONT.getCode(), contractNo);
                ComAttachmentFile repayIdCardBack = this.getFile(AttachmentUniqueCodeEnum.REPAY_IDCARD_BACK.getCode(), contractNo);
                ComAttachmentFile repayBankCardFront = this.getFile(AttachmentUniqueCodeEnum.REPAY_BANK_CARD_FRONT.getCode(), contractNo);
                ComAttachmentFile repayBankCardBack = this.getFile(AttachmentUniqueCodeEnum.REPAY_BANK_CARD_BACK.getCode(), contractNo);
                byte[] repayIdCardFrontBytes = comAttachmentFileService.downloadFileBytes(repayIdCardFront.getFileId());
                byte[] repayIdCardBackBytes = comAttachmentFileService.downloadFileBytes(repayIdCardBack.getFileId());
                ByteArrayInputStream repayIdCardFrontIn = new ByteArrayInputStream(repayIdCardFrontBytes);
                ByteArrayInputStream repayIdCardBackIn = new ByteArrayInputStream(repayIdCardBackBytes);
                BufferedImage repayIdCardFrontImage = ImageIO.read(repayIdCardFrontIn);
                BufferedImage repayIdCardBackImage = ImageIO.read(repayIdCardBackIn);
                BufferedImage bufferedImage = drawImg.mergeImage(repayIdCardFrontImage, repayIdCardBackImage, accountName + ":" + certNo);
                String fileName=accountName + "身份证-" + certNo + ".jpg";
                String tmpFile = fileProperties.getTempDir() + File.separator +fileName;
                File outPutFile = new File(tmpFile);
                ImageIO.write(bufferedImage, "jpg", outPutFile);
                UploadInputVo uploadInputVo = new UploadInputVo();
                uploadInputVo.setBusiNo(contractNo);
                uploadInputVo.setBelongNo(contractNo);
                uploadInputVo.setFileVersion("0");
                uploadInputVo.setFileSource("com_attachment_management");
                uploadInputVo.setFileName(fileName);
                uploadInputVo.setFileType("jpg");
                uploadInputVo.setAttachmentId(management.getId().toString());
                uploadInputVo.setAttachmentName(management.getAttachmentName());
                uploadInputVo.setIsElectronic("0");
                uploadInputVo.setFileStatus(FileStatusEnum.DRAFT.getCode());
                uploadInputVo.setArchiveClass(management.getArchiveClass());
                comAttachmentFileService.storeFileToOss(outPutFile, uploadInputVo);
                FileUtil.del(outPutFile);
            }else {
                log.info("未找到还款人身份证合成影像件类型，请在影像管理配置");
            }
        } catch (IOException e) {
            log.error("合同{}还款人身份证合成失败",contractNo,e);
        }
    }
    public void mergeRepayBankCard(String contractNo,String accountName,String accountNo) {
        try {
            ComAttachmentManagement management=this.getOne(Wrappers.<ComAttachmentManagement>lambdaQuery()
                    .eq(ComAttachmentManagement::getUniqueCode,AttachmentUniqueCodeEnum.REPAY_BANK_CARD_MERGE.getCode())
                    .eq(ComAttachmentManagement::getBusiNode,BusiNodeEnum.LOAN_APPLY.getCode()));
            if(!ObjectUtils.isEmpty(management)){
                ComAttachmentFile repayBankCardFront = this.getFile(AttachmentUniqueCodeEnum.REPAY_BANK_CARD_FRONT.getCode(), contractNo);
                ComAttachmentFile repayBankCardBack = this.getFile(AttachmentUniqueCodeEnum.REPAY_BANK_CARD_BACK.getCode(), contractNo);
                byte[] repayBankCardFrontBytes = comAttachmentFileService.downloadFileBytes(repayBankCardFront.getFileId());
                byte[] repayBankCardBackBytes = comAttachmentFileService.downloadFileBytes(repayBankCardBack.getFileId());
                ByteArrayInputStream repayBankCardFrontIn = new ByteArrayInputStream(repayBankCardFrontBytes);
                ByteArrayInputStream repayBankCardBackIn = new ByteArrayInputStream(repayBankCardBackBytes);
                BufferedImage repayBankCardFrontImage = ImageIO.read(repayBankCardFrontIn);
                BufferedImage repayBankCardBackImage = ImageIO.read(repayBankCardBackIn);
                BufferedImage bufferedImage = drawImg.mergeImage(repayBankCardFrontImage, repayBankCardBackImage, accountName + ":" + accountNo);
                String fileName=accountName + "还款卡-" + accountNo + ".jpg";
                String tmpFile = fileProperties.getTempDir() + File.separator +fileName;
                File outPutFile = new File(tmpFile);
                ImageIO.write(bufferedImage, "jpg", outPutFile);
                UploadInputVo uploadInputVo = new UploadInputVo();
                uploadInputVo.setBusiNo(contractNo);
                uploadInputVo.setBelongNo(contractNo);
                uploadInputVo.setFileVersion("0");
                uploadInputVo.setFileSource("com_attachment_management");
                uploadInputVo.setFileName(fileName);
                uploadInputVo.setFileType("jpg");
                uploadInputVo.setAttachmentId(management.getId().toString());
                uploadInputVo.setAttachmentName(management.getAttachmentName());
                uploadInputVo.setIsElectronic("0");
                uploadInputVo.setFileStatus(FileStatusEnum.DRAFT.getCode());
                uploadInputVo.setArchiveClass(management.getArchiveClass());
                comAttachmentFileService.storeFileToOss(outPutFile, uploadInputVo);
                FileUtil.del(outPutFile);
            }else {
                log.info("未找到还款卡合成影像件类型，请在影像管理配置");
            }
        } catch (IOException e) {
            log.error("合同{}还款卡合成失败",contractNo,e);
        }
    }
}
